from queue import Queue, Empty
from threading import *


class EventManager:
    __eventQueue = Queue()
    __handlers = {}

    def __init__(self):
        self.__active = True

    def start(self):
        self.__active = True

    def stop(self):
        self.__active = False

    def run(self):
        print('Event manager is running.')
        while self.__active is True:
            try:
                event = self.__eventQueue.get(block=True, timeout=1)
                self.__event_process(event)
            except Empty:
                pass

    def __event_process(self, event):
        if not isinstance(event, Event):
            raise Exception('Bad event class')

        if event.type_ in self.__handlers:
            for handler in self.__handlers[event.type_]:
                handler(event)

    @staticmethod
    def add_event_listener(type_, handler):
        try:
            handler_list = EventManager.__handlers[type_]
        except KeyError:
            handler_list = []

            EventManager.__handlers[type_] = handler_list
        if handler not in handler_list:
            handler_list.append(handler)
            print('[EventMgr] add event listener: ' + str(type_))

    @staticmethod
    def remove_event_listener(type_, handler):
        try:
            handler_list = EventManager.__handlers[type_]
        except KeyError:
            handler_list = []

            EventManager.__handlers[type_] = handler_list
        if handler in handler_list:
            handler_list.remove(handler)
            print('[EventMgr] remove event listener: ' + str(type_))

    @staticmethod
    def emit(event):
        print('[EventMgr] emit: ' + str(event.type_))

        EventManager.__eventQueue.put(event)


########################################################################

class Event:
    ON_APPLICATION_CLOSE = 0
    ON_FRAME_UPDATE = 1
    ON_END_OF_FILE = 2

    def __init__(self, type_=None, data={}):
        self.type_ = type_
        self.dict = data
